package edu.thu.studio.ormdesigner.persistent.impl;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.List;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

import edu.thu.studio.ormdesigner.model.ORMModel;
import edu.thu.studio.ormdesigner.model.diagram.Diagram;
import edu.thu.studio.ormdesigner.model.diagram.link.Link;
import edu.thu.studio.ormdesigner.model.diagram.link.LinkSet;
import edu.thu.studio.ormdesigner.model.diagram.node.Node;
import edu.thu.studio.ormdesigner.model.diagram.node.NodeSet;
import edu.thu.studio.ormdesigner.model.diagram.node.TableNode;
import edu.thu.studio.ormdesigner.model.diagram.node.ViewNode;
import edu.thu.studio.ormdesigner.model.domain.Domain;
import edu.thu.studio.ormdesigner.model.orm.table.Column;
import edu.thu.studio.ormdesigner.model.orm.table.Table;
import edu.thu.studio.ormdesigner.persistent.AnnotationJavaReflectionProvider;
import edu.thu.studio.ormdesigner.persistent.Persistent;

public class PersistentXmlImpl extends Persistent {
    
    public static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
    @Override
    public ORMModel load(InputStream in) throws Exception {
        XStream xstream = new XStream(new AnnotationJavaReflectionProvider(), new DomDriver("utf8"));
        xstream.processAnnotations(ORMModel.class);
        xstream.processAnnotations(TableNode.class);
        xstream.processAnnotations(ViewNode.class);
        
        ORMModel t = (ORMModel) xstream.fromXML(in);
        resetModel(t);
        
        return t;
    }
    
    private void resetModel(ORMModel t) {
        List<Domain> domainList = t.getDomains().getObjectList();
        // 设置column的指向domain的对象
        for (Table table : t.getTableSet().getObjectList()) {
            for (Column column : table.getColumns().getObjectList()) {
                if (null != column.getDomain() && column.getDomain().trim().length() > 0) {
                    for (Domain domain : domainList) {
                        if (column.getDomain().equals(domain.getId())) {
                            column.setDomainObject(domain);
                            break;
                        }
                    }
                }
            }
        }
        
        Iterator<Diagram> itpackage = t.getDiagrams().iterator();
        while (itpackage.hasNext()) {
            Diagram diagram = itpackage.next();
            NodeSet nodeset = diagram.getNodes();
            Iterator<Node> itnode = nodeset.iterator();
            // 设置下node的diagram
            while (itnode.hasNext()) {
                Node node = itnode.next();
                node.setDiagram(diagram);
                if (node instanceof ViewNode) {
                    node.setRefTable(t.getViewSet().get(node.getRefId()));
                } else {
                    node.setRefTable(t.getTableSet().get(node.getRefId()));
                }
            }
            
            // 设置link的source和target
            LinkSet linkset = diagram.getLinks();
            Iterator<Link> itlinksourcetarget = linkset.iterator();
            while (itlinksourcetarget.hasNext()) {
                Link link = itlinksourcetarget.next();
                
                Iterator<Node> itn = nodeset.iterator();
                while (itn.hasNext()) {
                    Node node = itn.next();
                    
                    if (node.getId().equals(link.getFrom())) {
                        link.setSource(node);
                    }
                    
                    if (node.getId().equals(link.getTo())) {
                        link.setTarget(node);
                    }
                }
            }
            
            Iterator<Link> itlinkconnect = linkset.iterator();
            while (itlinkconnect.hasNext()) {
                Link link = itlinkconnect.next();
                link.reconnect();
            }
        }
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
	public InputStream createInputStream(ORMModel model) throws IOException {
		InputStream inputStream = null;

		XStream xstream = new XStream(new DomDriver("UTF-8"));
		xstream.processAnnotations(ORMModel.class);
		xstream.processAnnotations(TableNode.class);
		xstream.processAnnotations(ViewNode.class);

		String schema = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
		String result = schema + xstream.toXML(model);

		inputStream = new ByteArrayInputStream(result.getBytes());

		return inputStream;
	}
}